/**
 * TableService使用示例
 * 本文件包含各种业务场景下TableService的使用方法
 * @author sun
 * @date 2024-07-13
 */

import { createTableService } from './AutoTableService';
import { QueryTools } from '@/utils/autoQuery/tools';
import { QueryOperator } from '@/utils/autoQuery/types';
import { Condition as QueryCondition, OrGroup, Range } from '@/utils/autoQuery/decorators';
import { QueryBuilder } from '@/utils/autoQuery/QueryBuilder';

/**
 * 基础使用示例
 * 展示常用的CRUD操作
 */
export function basicUsageExample() {
  // 定义城市服务类型
  const lifeline_test = createTableService<{
    name: string;
    birth: string;
    yellow: number;
    id: number;
    bookId: number;
  }>('lifeline_test_dome');

  // 基本查询示例 - 使用原始条件格式
  lifeline_test
    .query({
      page: 1,
      pageSize: 20,
      columns: ['id', 'name'],
      condition: ['and', ['like', 'yellow', '%1%']],
      params: {
        action: 'xxxx查询接口',
        no: '222',
      },
    })
    .then((res) => {
      console.log('查询结果:', res);
      console.log('第一条记录的出生日期:', res.rows[0]?.birth);
    });

  // 使用autoQuery构建查询条件
  const queryCondition = QueryTools.and(
    QueryTools.like('name', '张%'),
    QueryTools.greaterThan('yellow', 5),
  );

  // 使用autoQuery构建的条件进行查询
  lifeline_test
    .query({
      page: 1,
      pageSize: 10,
      condition: queryCondition,
      params: {
        action: '使用autoQuery的查询接口',
        no: '223',
      },
    })
    .then((res) => {
      console.log('使用autoQuery构建条件的查询结果:', res);
    });

  // 根据id查询
  lifeline_test
    .findById({
      id: 1,
      params: {
        action: 'xxxxfind接口',
        no: '333',
      },
    })
    .then((res) => {
      console.log('按ID查询结果:', res);
    });

  // 新增
  lifeline_test
    .create({
      data: {
        name: 'test',
        birth: '2024-01-01',
        yellow: 1,
      },
      params: {
        action: 'xxxx新增接口',
        no: '888',
      },
    })
    .then((res) => {
      console.log('新增结果:', res);
    });

  // 批量新增
  lifeline_test
    .batchCreate({
      list: [
        { name: 'test1', birth: '2024-01-01', yellow: 1 },
        { name: 'test2', birth: '2024-01-01', yellow: 2 },
      ],
      params: {
        action: 'xxxx批量新增接口',
        no: '999',
      },
    })
    .then((res) => {
      console.log('批量新增结果:', res);
    });

  // 更新 - 使用autoQuery构建更新条件
  const updateCondition = QueryTools.and(
    QueryTools.equal('id', 1001),
    QueryTools.notEqual('status', 0),
  );

  lifeline_test
    .update({
      data: {
        name: 'test3',
      },
      condition: updateCondition,
      params: {
        action: 'xxxx更新接口',
        no: '1000',
      },
    })
    .then((res) => {
      console.log('更新结果:', res);
    });

  lifeline_test
    .delete({
      data: { id: 122 },
      params: {
        action: 'xxxx删除接口',
        no: '1001',
      },
    })
    .then((res) => {
      console.log('删除结果:', res);
    });

  // 导出
  lifeline_test
    .exportToCsv({
      data: [],
      header: ['id', 'name', 'birth', 'yellow'],
      params: {
        action: 'xxxx导出接口',
        no: '1002',
      },
    })
    .then((res) => {
      console.log('导出结果:', res);
    });
}

/**
 * 混合操作-单表与关联
 * 展示复杂的混合操作和关联查询
 */
export function complexOperationsExample() {
  // 定义城市服务
  const lifeline_test = createTableService<{
    name: string;
    birth: string;
    yellow: number;
    id: number;
    bookId: number;
  }>('lifeline_test_dome');

  // 混合操作 - 使用autoQuery构建关联条件
  const bookIdCondition = QueryTools.equal('id', 'lifeline_test_dome.book_id');

  // 使用autoQuery构建查询条件
  const cityCondition = QueryTools.equal('id', 987001);
  const propsCondition = QueryTools.like('props', '%1%');
  const tableIdCondition = QueryTools.equal('id', 222);

  // 混合操作
  lifeline_test
    .crud({
      RequestParams: {
        where: cityCondition,
        opts: {
          crud: 'findby',
          jsoncolumns: ['book'],
          rship: {
            book: {
              tn: 't_book_dome',
              cols: {
                id: 'id',
                bookName: 'book_name',
              },
              where: bookIdCondition,
              opts: {
                jsonfn: 'object|array',
              },
            },
          },
        },
      },
      // 同时多表的操作 - 更灵活的方式
      tables: {
        a_table_dome: {
          where: propsCondition,
          opts: {
            crud: 'findby', // 使用findby替代query
          },
        },
        b_table_dome: {
          where: tableIdCondition,
          opts: {
            crud: 'delete',
          },
        },
      },
      params: {
        action: 'xxxx混合操作接口',
        no: '1003',
      },
    })
    .then((result) => {
      console.log('混合操作结果:', result);
    });
}

/**
 * 文章及其关联数据查询示例
 * 展示多层级关联查询
 */
export function articleRelationQueryExample() {
  // 查询文章及其分类和作者
  const articleService = createTableService<{
    id: number;
    articleTitle: string;
    content: string;
    categoryId: number;
    authors: string; // JSON字段，存储作者信息
  }>('article_dome');

  // 使用autoQuery构建条件
  const articleCondition = QueryTools.equal('id', 987001);
  const categoryCondition = QueryTools.equal('id', 'article_dome.category_id');
  const commentsCondition = QueryTools.equal('article_id', 'article_dome.id');
  const userCondition = QueryTools.equal('id', 'comment_dome.user_id');

  // 使用crud进行关联查询
  articleService
    .crud({
      RequestParams: {
        // 可以添加过滤条件
        where: articleCondition,
        // 配置选项
        opts: {
          // 操作类型为findby
          crud: 'findby',
          // 处理JSON字段
          jsoncolumns: ['authors'],
          // 关联查询配置
          rship: {
            // 关联分类表
            category: {
              tn: 'category_dome',
              cols: {
                id: 'id',
                name: 'category_name',
                level: 'level',
              },
              // 关联条件：category.id = article.category_id
              where: categoryCondition,
              opts: {
                // 返回为对象形式（一对一关系）
                jsonfn: 'object',
              },
            },
            // 关联评论表
            comments: {
              tn: 'comment_dome',
              cols: {
                id: 'id',
                content: 'content',
                userId: 'user_id',
                createTime: 'create_time',
              },
              // 关联条件：comment.article_id = article.id
              where: commentsCondition,
              opts: {
                // 返回为数组形式（一对多关系）
                jsonfn: 'array',
                // 嵌套关联查询评论的用户信息
                rship: {
                  user: {
                    tn: 'user_dome',
                    cols: {
                      id: 'id',
                      name: 'user_name',
                      avatar: 'avatar',
                    },
                    where: userCondition,
                    opts: {
                      jsonfn: 'object',
                    },
                  },
                },
              },
            },
          },
        },
      },
      params: {
        action: '查询文章详情',
        no: 'article001',
      },
    })
    .then((result) => {
      console.log('文章数据:', result);
      // 返回结果包含文章信息、分类信息和评论数组
      // 每条评论中又包含用户信息
    });
}

/**
 * 订单与订单明细事务操作示例
 * 展示事务内多表操作
 */
export function orderTransactionExample() {
  // 订单类型定义
  type Order = {
    id: number;
    orderNo: string;
    customerId: number;
    totalAmount: number;
    status: number;
    updateTime: string;
  };

  // 订单明细类型定义
  type OrderItem = {
    id: number;
    orderId: number;
    productId: number;
    productName: string;
    quantity: number;
    price: number;
  };

  // 示例：混合操作 - 同时更新订单和创建明细
  const orderService = createTableService<Order>('order_dome');

  // 使用autoQuery构建条件
  const orderIdCondition = QueryTools.equal('id', 1001);

  // 使用crud进行混合操作
  orderService
    .crud({
      // 主表操作
      RequestParams: {
        // 要更新的订单数据
        id: 1001, // 使用数字类型
        status: 1,
        updateTime: new Date().toISOString(),
        // 更新条件
        where: orderIdCondition,
        // 定义批量操作数据
        opts: {
          // 混合操作类型
          crud: 'update',
          // 使用replace模式（MySQL）
          replace: true,
        },
      },
      // 关联表操作 - 使用正确的类型
      tables: {
        // 创建订单明细
        order_item_dome: {
          // 批量创建多条明细记录 - 使用正确的类型
          rows: [
            {
              orderId: 1001, // 使用数字类型
              productId: 1001,
              productName: '高端笔记本电脑',
              quantity: 1,
              price: 9999.0,
            },
            {
              orderId: 1001, // 使用数字类型
              productId: 2001,
              productName: '无线鼠标',
              quantity: 2,
              price: 199.0,
            },
          ] as OrderItem[],
          opts: {
            // 指定操作类型为创建
            crud: 'create',
            // 主键配置
            pk: 'id',
            genkey: true,
          },
        },
      },
      // 全局选项
      opts: {
        // 启用事务
        tran: true,
      },
      // 额外的请求参数
      params: {
        action: '更新订单状态并添加明细',
        no: 'order001',
      },
    })
    .then((result) => {
      console.log('操作结果:', result);
    });
}

/**
 * 与autoQuery模块结合使用的示例
 * 展示如何使用智能查询构建器
 */
export function usingWithAutoQueryExample() {
  // 创建用户服务
  const userService = createTableService<{
    id: number;
    name: string;
    age: number;
    department: string;
    role: string;
    status: number;
    createdAt: string;
  }>('user_dome');

  // 查询条件对象 - 来自表单或API参数
  const searchParams = {
    name: '张*', // 开头匹配
    age: [18, 60], // 年龄范围
    department: '技术部', // 精确匹配
    role: ['admin', 'developer'], // 角色列表
    status: 1, // 状态活跃
    dateRange: ['2023-01-01', '2023-12-31'], // 创建时间范围
    // 以下是无效值，会被自动忽略
    email: '',
    phone: null,
    address: undefined,
  };

  // 使用智能查询构建器构建条件
  const condition = QueryTools.smartQuery(searchParams, {
    // 自定义字段处理
    fieldOperators: {
      // 将部门字段作为等于条件而不是默认的模糊匹配
      department: { operator: QueryOperator.EQUAL },
      // 将日期范围映射到createdAt字段
      dateRange: {
        handler: (field, value) => {
          if (Array.isArray(value) && value.length === 2) {
            return QueryTools.between('createdAt', value[0], value[1]);
          }
          return [];
        },
      },
    },
    // 排除的字段 - 这些字段不生成查询条件
    exclude: ['page', 'pageSize', 'sortField', 'sortOrder'],
    // 模糊匹配设置为false - 字符串不自动使用LIKE
    autoLike: false,
    // 特定字段分组 - 这里将name和department放在OR组中
    groups: {
      or: [['name', 'department']],
    },
  });

  // 分页查询
  userService
    .query({
      page: 1,
      pageSize: 20,
      condition,
      columns: ['id', 'name', 'age', 'department', 'role', 'status', 'createdAt'],
    })
    .then((result) => {
      console.log('查询结果:', result);
    });
}

/**
 * 高级过滤示例
 * 展示如何处理复杂的表单数据生成查询条件
 */
export function advancedFilteringExample() {
  // 创建产品服务
  const productService = createTableService<{
    id: number;
    name: string;
    price: number;
    category: string;
    tags: string; // 存储为JSON字符串
    stock: number;
    createTime: string;
    updateTime: string;
    status: number;
  }>('product_dome');

  // 模拟一个复杂的表单数据（包含一些空值）
  const formData = {
    // 基础信息搜索
    keyword: '智能', // 关键词搜索
    priceRange: [1000, 5000], // 价格范围
    categoriesSelected: ['电子', '家居'], // 所选分类
    statusOptions: [1, 2], // 状态选项（1=上架，2=促销）

    // 库存条件
    stockCondition: 'lowStock', // 库存条件(lowStock=库存低，outOfStock=无库存)

    // 日期条件
    dateType: 'createTime', // 日期类型(createTime=创建时间，updateTime=更新时间)
    dateRange: ['2023-01-01', '2023-12-31'], // 日期范围

    // 排序信息（不需要作为查询条件）
    sortField: 'price',
    sortOrder: 'desc',

    // 分页信息（不需要作为查询条件）
    page: 1,
    pageSize: 20,
  };

  // 使用autoQuery处理复杂条件 - 无需手动检查空值

  // 1. 关键词搜索 - QueryTools.or会自动处理里面的空条件
  const keywordCondition = QueryTools.or(
    QueryTools.like('name', formData.keyword),
    QueryTools.like('category', formData.keyword),
  );

  // 2. 价格范围 - QueryTools.range会自动处理空值
  const priceCondition = QueryTools.range(
    'price',
    formData.priceRange?.[0],
    formData.priceRange?.[1],
  );

  // 3. 分类条件 - QueryTools.in会自动处理空数组
  const categoryCondition = QueryTools.in('category', formData.categoriesSelected || []);

  // 4. 状态条件 - QueryTools.in会自动处理空数组
  const statusCondition = QueryTools.in('status', formData.statusOptions || []);

  // 5. 库存条件 - 条件分支处理
  let stockCondition;
  if (formData.stockCondition === 'lowStock') {
    stockCondition = QueryTools.lessThan('stock', 10);
  } else if (formData.stockCondition === 'outOfStock') {
    stockCondition = QueryTools.equal('stock', 0);
  } else {
    stockCondition = []; // 空条件会被AND自动忽略
  }

  // 6. 日期条件 - QueryTools.between会自动处理空值
  const dateFieldName = formData.dateType || 'createTime';
  const dateCondition = QueryTools.between(
    dateFieldName,
    formData.dateRange?.[0],
    formData.dateRange?.[1],
  );

  // 7. 组合所有条件 - QueryTools.and会自动过滤掉空条件
  const condition = QueryTools.and(
    keywordCondition,
    priceCondition,
    categoryCondition,
    statusCondition,
    stockCondition,
    dateCondition,
  );

  // 执行查询
  productService
    .query({
      page: formData.page,
      pageSize: formData.pageSize,
      condition,
    })
    .then((result) => {
      console.log('高级过滤查询结果:', result);
    });
}

/**
 * 智能查询构建器示例
 * 展示更简洁的查询条件构建方式
 */
export function smartQueryExample() {
  // 创建产品服务
  const productService = createTableService<{
    id: number;
    name: string;
    price: number;
    category: string;
    tags: string;
    stock: number;
    createTime: string;
    updateTime: string;
    status: number;
  }>('product_dome');

  // 模拟一个复杂的表单数据（包含一些空值）
  const formData = {
    keyword: '智能',
    priceRange: [1000, 5000],
    categoriesSelected: ['电子', '家居'],
    statusOptions: [1, 2],
    stockCondition: 'lowStock',
    dateType: 'createTime',
    dateRange: ['2023-01-01', '2023-12-31'],
    // 一些空值
    tags: [],
    description: '',
    supplier: null,
    address: undefined,
    // 分页信息
    page: 1,
    pageSize: 20,
  };

  // 直接使用smartQuery一次性处理所有条件（包括空值处理）
  const condition = QueryTools.smartQuery(formData, {
    // 自定义字段处理
    fieldOperators: {
      // 处理关键词
      keyword: {
        handler: (field, value) =>
          QueryTools.or(QueryTools.like('name', value), QueryTools.like('category', value)),
      },

      // 处理价格范围
      priceRange: {
        handler: (field, value) => QueryTools.range('price', value[0], value[1]),
      },

      // 处理分类
      categoriesSelected: {
        handler: (field, value) => QueryTools.in('category', value),
      },

      // 处理状态
      statusOptions: {
        handler: (field, value) => QueryTools.in('status', value),
      },

      // 处理库存条件
      stockCondition: {
        handler: (field, value) => {
          if (value === 'lowStock') {
            return QueryTools.lessThan('stock', 10);
          } else if (value === 'outOfStock') {
            return QueryTools.equal('stock', 0);
          }
          return [];
        },
      },

      // 处理日期范围
      dateRange: {
        handler: (field, value) => {
          if (Array.isArray(value) && value.length === 2) {
            const dateField = formData.dateType || 'createTime';
            return QueryTools.between(dateField, value[0], value[1]);
          }
          return [];
        },
      },
    },

    // 排除非搜索字段
    exclude: ['page', 'pageSize', 'sortField', 'sortOrder', 'dateType'],
  });

  // 执行查询
  productService
    .query({
      page: formData.page || 1,
      pageSize: formData.pageSize || 20,
      condition,
    })
    .then((result) => {
      console.log('智能查询构建器结果:', result);
    });
}

/**
 * 使用装饰器方式构建查询条件
 * 展示如何结合装饰器与autoQuery模块
 */
export function decoratorExample() {
  // 产品类型定义
  interface Product {
    id: number;
    name: string;
    price: number;
    category: string;
    brand: string;
    tags: string[];
    createTime: Date;
    status: number;
  }

  // 品牌条件类
  class BrandCondition {
    @QueryCondition(QueryOperator.EQUAL)
    brand?: string;

    constructor(brand?: string) {
      this.brand = brand;
    }
  }

  // 产品查询条件类
  class ProductSearchCondition {
    // 基本条件 - 使用装饰器定义字段与操作符映射
    @QueryCondition(QueryOperator.LIKE)
    name?: string;

    @QueryCondition(QueryOperator.EQUAL)
    category?: string;

    // 范围条件
    @Range('price')
    priceRange?: [number, number];

    // 日期范围
    @Range('createTime')
    dateRange?: [Date, Date];

    // 嵌套OR条件组
    @OrGroup()
    brands?: BrandCondition[];

    // 状态条件
    @QueryCondition(QueryOperator.IN)
    status?: number[];

    constructor(init?: Partial<ProductSearchCondition>) {
      if (init) {
        Object.assign(this, init);
      }
    }
  }

  // 创建产品服务
  const productService = createTableService<Product>('product_dome');

  // 创建查询条件实例
  const searchCondition = new ProductSearchCondition({
    name: '笔记本', // 会自动转换为模糊匹配: %笔记本%
    category: '电子产品',
    priceRange: [5000, 10000],
    dateRange: [new Date('2023-01-01'), new Date('2023-12-31')],
    brands: [new BrandCondition('苹果'), new BrandCondition('联想')],
    status: [1, 2], // 上架和促销状态
  });

  // 使用QueryBuilder从装饰器构建条件
  const condition = QueryBuilder.fromDecorators(searchCondition);

  console.log('使用装饰器构建的查询条件:', JSON.stringify(condition, null, 2));

  // 执行查询
  productService
    .query({
      page: 1,
      pageSize: 20,
      condition,
    })
    .then((result) => {
      console.log('装饰器查询结果:', result);
    });

  // 组合使用装饰器和QueryTools
  // 在某些情况下，我们可能需要在装饰器生成的条件基础上添加更多条件
  const decoratorCondition = QueryBuilder.fromDecorators(searchCondition);
  const additionalCondition = QueryTools.and(
    QueryTools.greaterThan('stock', 10),
    QueryTools.equal('isHot', true),
  );

  // 组合两种条件
  const combinedCondition = QueryTools.and(decoratorCondition, additionalCondition);

  // 执行组合查询
  productService
    .query({
      page: 1,
      pageSize: 20,
      condition: combinedCondition,
    })
    .then((result) => {
      console.log('装饰器和工具函数组合查询结果:', result);
    });
}

/**
 * 高级opts参数用法示例
 * 展示符合autoApi.md文档中的各种opts参数
 */
export function advancedOptsExample() {
  // 创建组织部门服务
  const departmentService = createTableService<{
    id: number;
    name: string;
    code: string;
    parentId: number;
    level: number;
    path: string;
    status: number;
    managerIds: string; // 部门负责人ID列表，存储为逗号分隔的字符串
    members: string; // 部门成员，JSON格式
    contactInfo: string; // 联系方式，JSON格式
    idCard: string; // 证件号码
    email: string; // 电子邮箱
    phone: string; // 联系电话
  }>('department_dome');

  // 使用arraycolumns将逗号分隔的字符串与数组互转
  departmentService
    .create({
      data: {
        name: '研发部',
        code: 'DEV',
        parentId: 0,
        level: 1,
        // 这里应该使用字符串，让金牛座后端处理转换
        managerIds: '1001,1002,1003',
        // 这里应该使用JSON字符串，让金牛座后端处理转换
        members: JSON.stringify({
          total: 30,
          managers: ['张三', '李四'],
          groups: [
            { name: '前端组', count: 10 },
            { name: '后端组', count: 15 },
            { name: '测试组', count: 5 },
          ],
        }),
        contactInfo: JSON.stringify({
          address: '上海市浦东新区xx路xx号',
          tel: '021-88889999',
        }),
        idCard: '310123456789012345',
        email: 'dev@example.com',
        phone: '13812345678',
        status: 1,
        opts: {
          jsoncolumns: ['members', 'contactInfo'],
        },
      },
      params: {
        action: '创建部门',
        no: 'dept001',
      },
    })
    .then((res) => {
      console.log('创建部门结果:', res);
    });

  // 查询部门信息 - 使用rsstyle和transform变换
  departmentService
    .crud({
      RequestParams: {
        where: ['=', 'status', 1],
        opts: {
          crud: 'findby',
          // 说明：以下是金牛座API支持的参数，实际调用时通过底层传递
          // rsstyle: "camel", // 使用驼峰风格：managerId
          // jsoncolumns: ["members", "contactInfo"],
          // transform: [
          //   ["btree", ["parentId", "id"]],
          //   ["mask", [
          //     "idCard", "idcard",
          //     "email", "email",
          //     "phone", "b3a4"
          //   ]]
          // ]
        },
      },
      params: {
        action: '查询组织架构',
        no: 'dept002',
      },
    })
    .then((result) => {
      console.log('部门查询结果(树状结构):', result);
      // 结果已经是树状结构，顶级部门包含children数组
      // 敏感信息已经过脱敏处理
    });

  // 对数据进行导出 - 说明金牛座支持的导出功能
  departmentService
    .exportToCsv({
      data: [], // 实际使用时，这里应该填充需要导出的数据
      header: ['id', '部门ID', 'name', '部门名称', 'code', '部门编码'],
      params: {
        action: '导出部门数据',
        no: 'dept003',
      },
    })
    .then((result) => {
      console.log('部门数据导出结果:', result);
    });

  // 说明：以下是金牛座API文档中的opts参数说明的示例，实际使用时可能需要调整接口定义
  console.log(`
金牛座API支持的opts参数：
1. pk: string - 主键名称，使用后台程序生成UUID时才需要指定
2. genkey: boolean - 是否由后端生成主键，与pk配合使用
3. snake: boolean - 是否将驼峰key转成下划线，如"userName"->"user_name"
4. jsoncolumns: array - 指定JSON字段名称，自动转换JSON和字符串
5. arraycolumns: array - 指定列在"a,b,c"和["a","b","c"]之间转换
6. rsstyle: string - 查询结果字段风格，支持"camel"、"snake"、"kebab"等
7. rship: object - 获取关联表数据
8. transform: array - 数据变换函数，如btree构建树结构、mask数据脱敏等
9. replace: boolean - 是否使用replace into语法（仅MySQL支持）
10. crud: string - 混合操作时指定操作类型："create"、"update"、"delete"、"http"
11. tran: boolean - 是否使用事务模式
	`);
}

/**
 * 运行所有示例
 */
export function runAllExamples() {
  console.log('=== 开始运行 TableService 示例 ===');

  // 运行基本示例
  basicUsageExample();

  // 运行复杂混合操作示例
  complexOperationsExample();

  // 运行文章关联查询示例
  articleRelationQueryExample();

  // 运行订单事务示例
  orderTransactionExample();

  // 运行与autoQuery集成示例
  usingWithAutoQueryExample();

  // 运行高级过滤示例
  advancedFilteringExample();

  // 运行智能查询构建器示例
  smartQueryExample();

  // 运行装饰器示例
  decoratorExample();

  // 运行高级opts参数示例
  advancedOptsExample();

  console.log('=== TableService 示例运行完成 ===');
}
